Skip to content

feat(tui): add configurable keybindings via config#217

Merged
jongio merged 3 commits into
mainfrom
idea/configurable-keybindings
Jul 6, 2026
Merged

feat(tui): add configurable keybindings via config#217
jongio merged 3 commits into
mainfrom
idea/configurable-keybindings

Conversation

@jongio

@jongio jongio commented Jul 3, 2026

Copy link
Copy Markdown
Owner

Summary

Adds a keybindings config map so users can remap any keyboard shortcut in the TUI. Closes #210.

Keys in the map are action names (for example search, quit, cmd_palette) and values are comma-separated key lists (for example /,ctrl+f). Listed actions replace their default keys; any action you do not list keeps its default.

What changed

  • internal/config/config.go: new Keybindings map[string]string field (keybindings in JSON, omitempty).
  • internal/tui/keys.go: refactored the package key map so it is produced by defaultKeyMap(). Added a registry of remappable actions (keybindingEntries, keybindingActionNames), a parseKeyList helper, and a pure applyKeybindingOverrides that returns a new key map plus warnings.
  • internal/tui/model.go: NewModel applies user overrides to the global key map right after theme resolution and logs any warnings via slog.
  • README.md: documents the option, adds a "Customizing Keybindings" section with the full action-name list, and updates the example config.
  • docs/keybindings.md: note at the top pointing to the remap capability.

Behavior and safety

  • Unknown action names are ignored with a logged warning.
  • An override that has no valid keys is ignored with a warning.
  • If a remap collides with a key another action uses, that remap is dropped and the default is kept, so a bad entry never leaves an action unreachable. Conflict resolution is deterministic (sorted) and terminates because the built-in defaults never collide.
  • Each remapped action keeps its original help description; the help hint text is regenerated from the new keys.

Acceptance criteria

  • Users can remap shortcuts through config.json.
  • Unlisted actions keep their defaults.
  • Invalid or conflicting entries fall back to defaults instead of breaking input.
  • The full list of action names is documented.

Testing

  • go build ./...
  • go vet ./...
  • golangci-lint run ./... (0 issues)
  • go test ./... -count=1 (all packages pass)

New internal/tui/keys_test.go covers no-op overrides, simple remaps, description preservation, unknown actions, empty values, default-conflict reverts, conflict-free swaps, two-override conflicts, key de-duplication, base immutability, and an end-to-end key.Matches check on a remapped binding.

@jongio jongio added the idea Feature idea from the idea pipeline label Jul 3, 2026
@jongio jongio self-assigned this Jul 3, 2026
jongio and others added 3 commits July 5, 2026 22:46
Add a "keybindings" config map that remaps keyboard shortcuts. Keys are
action names (search, quit, cmd_palette, etc.) and values are
comma-separated key lists. Listed actions replace their default keys;
unlisted actions keep their defaults. Unknown action names and keys that
collide with another action are skipped with a logged warning, so a bad
entry never leaves an action unreachable.

Refactor keys.go so the package key map is built by defaultKeyMap() and
add a registry of remappable actions plus a pure applyKeybindingOverrides
that resolves conflicts deterministically. NewModel applies user overrides
to the global key map before the UI reads it.

Closes #210

Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
The deadcode check flags helpers used only by tests. Derive the action name set directly from keybindingEntries in the test instead.

Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
@jongio jongio force-pushed the idea/configurable-keybindings branch from 7f9f3db to 063ab65 Compare July 6, 2026 05:48
@jongio jongio merged commit 760653d into main Jul 6, 2026
2 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

idea Feature idea from the idea pipeline

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Add configurable keybindings via config

1 participant